home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga CD-Sensation: Golden Games
/
Amiga CD-Sensation - Ausgabe 2 - Golden Games (1996)(GTI - Schatztruhe)(DE)[!].iso
/
Brain Activity
/
Rubik
/
source
/
solve.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-08-11
|
10KB
|
696 lines
/* I couldn't get an elegant tree searcher to work. Hence this kludge. */
#include "sequences.c"
short failed;
short waiting_output;
unsigned char output_buffer[20];
extern char tr [120];
extern struct one_square square[56];
extern void showtwist (short, short);
extern struct IntuiMessage *msg, *getmsg();
extern struct Window *wnd1,*wnd2;
struct IntuiMessage *flush()
{
unsigned char move;
short layer,direc;
short i;
msg = NULL;
while (waiting_output && ((msg = getmsg()) == NULL))
{
move = output_buffer[0];
layer = --move/3;
if ((direc = (move % 3)) == 0)
direc = -1;
showtwist (layer,direc);
for (i=0; i < waiting_output; i++)
output_buffer[i] = output_buffer[i+1];
--waiting_output;
}
return (msg);
}
void output (unsigned char move)
{
output_buffer [waiting_output++] = move;
}
void cornerseq (short seq)
{
unsigned short i;
for (i=0; i<6; i++)
output(corner5[seq][i]);
}
short checkcorner
(
short offset,
short a, short b, short c,
short x, short y, short z
)
{
short corner = 0;
if (square[x].colour == a)
{
if
(
((square[y].colour == b) && (square[z].colour == c)) ||
((square[y].colour == c) && (square[z].colour == b))
)
corner = 1 + offset;
}
else if (square[y].colour == a)
{
if
(
((square[x].colour == b) && (square[z].colour == c)) ||
((square[x].colour == c) && (square[z].colour == b))
)
corner = 2 + offset;
}
else if (square[z].colour == a)
{
if
(
((square[x].colour == b) && (square[y].colour == c)) ||
((square[x].colour == c) && (square[y].colour == b))
)
corner = 3 + offset;
}
return (corner);
}
short findcorner (short a, short b, short c)
{
short corner;
a = square[a].colour;
b = square[b].colour;
c = square[c].colour;
if
(
((corner = checkcorner(0,a,b,c,0,18,36)) == 0) &&
((corner = checkcorner(3,a,b,c,2,45,20)) == 0) &&
((corner = checkcorner(6,a,b,c,6,42,27)) == 0) &&
((corner = checkcorner(9,a,b,c,8,29,51)) == 0) &&
((corner = checkcorner(12,a,b,c,9,38,24)) == 0) &&
((corner = checkcorner(15,a,b,c,11,26,47)) == 0) &&
((corner = checkcorner(18,a,b,c,15,33,44)) == 0)
)
corner = checkcorner(21,a,b,c,17,53,35);
return (corner);
}
void edgeseq (short seq)
{
unsigned short i;
for (i=0; i<6; i++)
output(edge4[seq][i]);
}
void edgeseq2 (short seq)
{
unsigned short i;
for (i=0; i<5; i++)
output(edge5[seq][i]);
}
short checkedge
(
short offset,
short a, short b,
short x, short y
)
{
short edge = 0;
if ((square[x].colour == a) && (square[y].colour == b))
edge = 1 + offset;
else if ((square[x].colour == b) && (square[y].colour == a))
edge = 2 + offset;
return (edge);
}
short findedge (short a, short b)
{
short edge;
a = square[a].colour;
b = square[b].colour;
if (
((edge = checkedge(0,a,b,1,19)) == 0) &&
((edge = checkedge(2,a,b,3,39)) == 0) &&
((edge = checkedge(4,a,b,5,48)) == 0) &&
((edge = checkedge(6,a,b,7,28)) == 0) &&
((edge = checkedge(8,a,b,10,25)) == 0) &&
((edge = checkedge(10,a,b,12,41)) == 0) &&
((edge = checkedge(12,a,b,14,50)) == 0) &&
((edge = checkedge(14,a,b,16,34)) == 0) &&
((edge = checkedge(16,a,b,21,37)) == 0) &&
((edge = checkedge(18,a,b,23,46)) == 0) &&
((edge = checkedge(20,a,b,30,43)) == 0)
)
edge = checkedge(22,a,b,32,52);
return (edge);
}
void edgesequence (int seq)
{
short i,j;
unsigned char u;
if (seq < 24)
for (i = 1; i <= edge1[seq][0]; i++)
output (edge1[seq][i]);
else
for (i = 1; i <= edge2[seq-24][0]; i++)
{
if ((u = edge2[seq-24][i]) < 19)
output (u);
else
for (j = 1; j <= edge3[u-19][0]; j++)
output (edge3[u-19][j]);
}
}
struct IntuiMessage *edgefix(short up, short right, short down)
{
short i;
if ((findedge(right,up) == 1) && (findedge(right,down) == 7))
return (NULL);
if ((i = findedge(down,right)) == 0)
{
failed = 1;
return (NULL);
}
if (i > 1)
edgesequence(i-2);
if (msg = flush())
return (msg);
if ((i = findedge(right,up)) < 3)
{
failed = 1;
return (0);
}
edgesequence(i + 21);
return (flush());
}
struct IntuiMessage *solve()
{
short i,j;
if (msg = flush())
return (msg);
/* get right corners correct */
if ((i = findcorner(4,22,40)-2) < -1)
return (NULL);
if (i >= 0)
for (j=1; j<=corner1[i][0]; j++)
output (corner1[i][j]);
if (msg = flush())
return (msg);
if ((i = findcorner(4,49,22)-5) < -1)
return (NULL);
if (i >= 0)
for (j=1; j<=corner2[i][0]; j++)
output (corner2[i][j]);
if (msg = flush())
return(msg);
if ((i = findcorner(4,40,31)-8) < -1)
return (NULL);
if (i >= 0)
for (j=1; j<=corner3[i][0]; j++)
output (corner3[i][j]);
if (msg = flush())
return(msg);
if ((i = findcorner(4,31,49)-11) < -1)
return (NULL);
if (i >= 0)
for (j=1; j<=corner4[i][0]; j++)
output (corner4[i][j]);
if (msg = flush())
return(msg);
/* get left corners in position */
if ((i = findcorner(13,40,22)-13) < 0)
return (NULL);
switch (i/3)
{
case 0:
break;
case 1:
output (5);
break;
case 2:
output (4);
break;
case 3:
output (6);
break;
default:
return (NULL);
}
if (msg = flush())
return(msg);
if ((i = findcorner(13,22,49)-16) < 0)
return (NULL);
switch (i/3)
{
case 0:
break;
case 1:
output (5);
output (8);
output (4);
output (11);
output (5);
output (7);
output (4);
output (10);
break;
case 2:
output (11);
output (5);
output (8);
output (4);
output (10);
output (5);
output (7);
output (4);
break;
default:
return (NULL);
}
if (msg = flush())
return(msg);
if ((i = findcorner(13,31,40)-19) < 0)
return (NULL);
switch (i/3)
{
case 0:
break;
case 1:
output (4);
output (17);
output (5);
output (14);
output (4);
output (16);
output (5);
output (13);
output (4);
break;
default:
return (NULL);
}
if (msg = flush())
return(msg);
/* get left corners oriented */
if ((i = findcorner(13,40,22)-13) < 0)
return (NULL);
switch (i)
{
case 0:
break;
case 1:
cornerseq (1);
if (msg = flush())
return (msg);
if (findcorner(13,22,49)==18)
{
output (5);
cornerseq (0);
output (4);
}
else if (findcorner(13,31,40)==21)
{
output (4);
cornerseq (0);
output (5);
}
else
{
output (6);
cornerseq (0);
output (6);
}
break;
case 2:
cornerseq (0);
if (msg = flush())
return (msg);
if (findcorner(13,22,49)==17)
{
output (5);
cornerseq (1);
output (4);
}
else if (findcorner(13,31,40)==20)
{
output (4);
cornerseq (1);
output (5);
}
else
{
output (6);
cornerseq (1);
output (6);
}
break;
default:
return (NULL);
}
if (msg = flush())
return(msg);
if ((i = findcorner(13,22,49)-16) < 0)
return (NULL);
switch (i)
{
case 0:
break;
case 1:
cornerseq (3);
if (msg = flush())
return (msg);
if (findcorner(13,31,40)==21)
{
output (6);
cornerseq (2);
output (6);
}
else
{
output (5);
cornerseq (2);
output (4);
}
break;
case 2:
cornerseq (2);
if (msg = flush())
return (msg);
if (findcorner(13,31,40)==20)
{
output (6);
cornerseq (3);
output (6);
}
else
{
output (5);
cornerseq (3);
output (4);
}
break;
default:
return (NULL);
}
if (msg = flush())
return(msg);
if ((i = findcorner(13,31,40)-19) < 0)
return (NULL);
switch (i)
{
case 0:
break;
case 1:
cornerseq (5);
output (4);
cornerseq (4);
output (5);
break;
case 2:
cornerseq (4);
output (4);
cornerseq (5);
output (5);
break;
default:
return (NULL);
}
if (msg = flush())
return (msg);
if ((i = findcorner(13,49,31)) != 22)
return (NULL);
/* make top and bottom edges correct */
failed = 0;
if (msg = edgefix(22,4,31))
return (msg);
if (failed)
return (NULL);
output (7);
output (10);
if (msg = flush())
return(msg);
if (msg = edgefix(22,40,31))
return (msg);
if (failed)
return (NULL);
output (7);
output (10);
if (msg = flush())
return (msg);
if (msg = edgefix(22,13,31))
return (msg);
if (failed)
return (NULL);
output (7);
output (10);
if (msg = flush())
return(msg);
if (msg = edgefix(22,49,31))
return (msg);
if (failed)
return (NULL);
output (7);
output (10);
if (msg = flush())
return(msg);
/* get middle slice edges into position */
switch (findedge(4,40))
{
case 3:
case 4:
break;
case 5:
case 6:
edgeseq (0);
break;
case 11:
case 12:
edgeseq (1);
break;
case 13:
case 14:
edgeseq (2);
break;
default:
return (NULL);
}
if (msg = flush())
return(msg);
switch (findedge(13,49))
{
case 5:
case 6:
edgeseq (3);
break;
case 11:
case 12:
edgeseq (4);
break;
case 13:
case 14:
break;
default:
return (NULL);
}
if (msg = flush())
return(msg);
/* get middle edges oriented */
if (findedge(4,40) == 4)
{
edgeseq2 (0);
if (msg = flush())
return(msg);
if (findedge(4,49) == 6)
{
output (7);
output (10);
edgeseq2 (3);
output (8);
output (11);
}
else if (findedge(13,40) == 12)
{
output (8);
output (11);
edgeseq2 (4);
output (7);
output (10);
}
else
{
output (9);
output (12);
edgeseq2 (5);
output (9);
output (12);
}
}
if (msg = flush())
return(msg);
if (findedge(4,49) == 6)
{
edgeseq2 (1);
if (msg = flush())
return(msg);
if (findedge(13,40) == 12)
{
output (9);
output (12);
edgeseq2 (4);
output (9);
output (12);
}
else
{
output (7);
output (10);
edgeseq2 (5);
output (8);
output (11);
}
}
if (msg = flush())
return(msg);
if (findedge(13,40) == 12)
{
edgeseq2 (2);
output (8);
output (11);
edgeseq2 (5);
output (7);
output (10);
}
if (msg = flush())
return(msg);
/* if (findedge(13,49) != 13)
return (NULL);
*/
return (NULL);
}